package com.cloudcc.mobile.weight;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.text.style.StyleSpan;
import android.text.style.TextAppearanceSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;

public class RichEditText extends EditText{
	int size=18;
	int color=Color.BLACK;
	private String mark="[img] ";
	private  OnImageClickListener onClick;
	private OnSelectionChanged onSelectionChanged;
	private Context mContext;
	public RichEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mContext=context;
		// TODO Auto-generated constructor stub
	}

	public RichEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext=context;
	}

	public RichEditText(Context context) {
		super(context);
		mContext=context;
	}
	
	//加粗
	public void enabledBlod(boolean enabled){
		Spannable sp=getEditableText();
		if (enabled) {
			sp.setSpan(new StyleSpan(Typeface.BOLD),getSelectionStart(),getSelectionEnd(), Spanned.SPAN_MARK_POINT);
		}else{
			int prologueStart = Integer.MAX_VALUE;
			int epilogueEnd = -1;
			StyleSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionEnd(), StyleSpan.class);
			for (StyleSpan span : spans) {
				if (span.getStyle() == Typeface.BOLD) {
					int spanStart = sp.getSpanStart(span);
					if (spanStart < getSelectionStart()) {
						prologueStart = Math.min(prologueStart, spanStart);
					}
					int spanEnd = sp.getSpanEnd(span);

					if (spanEnd > getSelectionEnd()) {
						epilogueEnd = Math.max(epilogueEnd, spanEnd);
					}
					sp.removeSpan(span);
				}
			}
			if (prologueStart < Integer.MAX_VALUE) {
				sp.setSpan(new StyleSpan(Typeface.BOLD), prologueStart,
						getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
			if (epilogueEnd > -1) {
				sp.setSpan(new StyleSpan(Typeface.BOLD), getSelectionEnd(), epilogueEnd,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
		}
	}
	
	//斜体
	public void enabledItalic(boolean enabled){
		Spannable sp=getEditableText();
		if (enabled) {
			sp.setSpan(new StyleSpan(Typeface.ITALIC),getSelectionStart(),getSelectionEnd(), Spanned.SPAN_MARK_POINT);
		}else{
			int prologueStart = Integer.MAX_VALUE;
			int epilogueEnd = -1;
			StyleSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionEnd(), StyleSpan.class);
			for (StyleSpan span : spans) {
				if (span.getStyle() == Typeface.ITALIC) {
					int spanStart = sp.getSpanStart(span);
					if (spanStart < getSelectionStart()) {
						prologueStart = Math.min(prologueStart, spanStart);
					}
					int spanEnd = sp.getSpanEnd(span);

					if (spanEnd > getSelectionEnd()) {
						epilogueEnd = Math.max(epilogueEnd, spanEnd);
					}
					sp.removeSpan(span);
				}
			}
			if (prologueStart < Integer.MAX_VALUE) {
				sp.setSpan(new StyleSpan(Typeface.ITALIC), prologueStart,
						getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
			if (epilogueEnd > -1) {
				sp.setSpan(new StyleSpan(Typeface.ITALIC), getSelectionEnd(), epilogueEnd,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
		}
	}
	
	//下划线
	public void enabledUnderline(boolean enabled){
		Spannable sp=getEditableText();
		if (enabled) {
			sp.setSpan(new UnderlineSpan(),getSelectionStart(),getSelectionEnd(), Spanned.SPAN_MARK_POINT);
		}else{
			int prologueStart = Integer.MAX_VALUE;
			int epilogueEnd = -1;
			UnderlineSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionEnd(), UnderlineSpan.class);
			for (UnderlineSpan span : spans) {
					int spanStart = sp.getSpanStart(span);
					if (spanStart < getSelectionStart()) {
						prologueStart = Math.min(prologueStart, spanStart);
					}
					int spanEnd = sp.getSpanEnd(span);

					if (spanEnd > getSelectionEnd()) {
						epilogueEnd = Math.max(epilogueEnd, spanEnd);
					}
					sp.removeSpan(span);
			}
			if (prologueStart < Integer.MAX_VALUE) {
				sp.setSpan(new UnderlineSpan(), prologueStart,
						getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
			if (epilogueEnd > -1) {
				sp.setSpan(new UnderlineSpan(), getSelectionEnd(), epilogueEnd,
						Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
		}
	}
	
	public boolean blodInSelection(){
		Spannable sp=getEditableText();
		StyleSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionStart(), StyleSpan.class);
		for (StyleSpan span : spans) {
			if (span.getStyle() == Typeface.BOLD) {
				return true;
			}
		}
		return false;
	}
	public boolean italicInSelection(){
		Spannable sp=getEditableText();
		StyleSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionStart(), StyleSpan.class);
		for (StyleSpan span : spans) {
			if (span.getStyle() == Typeface.ITALIC) {
				return true;
			}
		}
		return false;
	}
	public boolean underLineInSelection(){
		Spannable sp=getEditableText();
		return sp.getSpans(getSelectionStart(),getSelectionEnd(), UnderlineSpan.class).length>0;
	}
	
	@Override
	protected void onSelectionChanged(int selStart, int selEnd) {
		if (onSelectionChanged!=null) {
			onSelectionChanged.onChanged(blodInSelection(), italicInSelection(), underLineInSelection());
		}
		super.onSelectionChanged(selStart, selEnd);
	}	
	
	public void setOnSelectionChanged(OnSelectionChanged onSelectionChanged){
		this.onSelectionChanged=onSelectionChanged;
	}
	
	
	
	//字体颜色和大小
	public void setCurrentText(int color,int size){
		Spannable sp=getEditableText();
		if (getSelectionStart()==getSelectionEnd()) {
			if (color==this.color&&size==this.size) {
				return;
			}else{
				int prologueStart = Integer.MAX_VALUE;
				int epilogueEnd = -1;
				TextAppearanceSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionEnd(), TextAppearanceSpan.class);
				for (TextAppearanceSpan span : spans) {
					if (span.getTextSize() == this.size&&span.getTextColor().getDefaultColor()==this.color) {
						int spanStart = sp.getSpanStart(span);
						if (spanStart < getSelectionStart()) {
							prologueStart = Math.min(prologueStart, spanStart);
						}
						int spanEnd = sp.getSpanEnd(span);

						if (spanEnd > getSelectionEnd()) {
							epilogueEnd = Math.max(epilogueEnd, spanEnd);
						}
						sp.removeSpan(span);
					}
				}
				if (prologueStart < Integer.MAX_VALUE) {
					sp.setSpan(new TextAppearanceSpan(null, 0, this.size, new ColorStateList(new int[][]{{0}}, new int[]{this.color}), null),prologueStart,getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}
				if (epilogueEnd > -1) {
					sp.setSpan(new TextAppearanceSpan(null, 0, this.size, new ColorStateList(new int[][]{{0}}, new int[]{this.color}), null),getSelectionEnd(),epilogueEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
				}
			}
			sp.setSpan(new TextAppearanceSpan(null, 0, size, new ColorStateList(new int[][]{{0}}, new int[]{color}), null),getSelectionStart(),getSelectionEnd(), Spannable.SPAN_MARK_POINT);
		}else{
			int prologueStart =-1;
			int epilogueEnd =  Integer.MAX_VALUE;
			TextAppearanceSpan[] spans=sp.getSpans(getSelectionStart(),getSelectionEnd(), TextAppearanceSpan.class);
			for (TextAppearanceSpan span : spans) {
				if (span.getTextSize()==size&&span.getTextColor().getDefaultColor()==color) {
					int spanStart = sp.getSpanStart(span);
					if (spanStart < getSelectionStart()) {
						prologueStart = Math.max(prologueStart, spanStart);
					}
					int spanEnd = sp.getSpanEnd(span);

					if (spanEnd > getSelectionEnd()) {
						epilogueEnd = Math.min(epilogueEnd, spanEnd);
					}
					sp.removeSpan(span);
				}
			}
			if (prologueStart >-1) {
				sp.setSpan(new TextAppearanceSpan(null, 0, size, new ColorStateList(new int[][]{{0}}, new int[]{color}), null),prologueStart,getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
			if (epilogueEnd <Integer.MAX_VALUE) {
				sp.setSpan(new TextAppearanceSpan(null, 0, size, new ColorStateList(new int[][]{{0}}, new int[]{color}), null),getSelectionEnd(),epilogueEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			}
			sp.setSpan(new TextAppearanceSpan(null, 0, size, new ColorStateList(new int[][]{{0}}, new int[]{color}), null),
					prologueStart >-1 ? prologueStart
							: getSelectionStart(), epilogueEnd <Integer.MAX_VALUE ? epilogueEnd
							:getSelectionEnd(),  Spannable.SPAN_MARK_POINT);
		}
		this.color=color;
		this.size=size;
	}
	
	public int getCurrentSize(){
		return size;
	}
	public int getCurrentColor(){
		return color;
	}
	
	
	public void addImage(final String path){
		Spannable sp=getEditableText();
		int start=getSelectionStart();
		int end=getSelectionEnd();
		((Editable) sp).insert(getSelectionStart(), mark);
		Drawable drawable=compressImage(path);
		int width=drawable.getIntrinsicWidth();
		int height=drawable.getIntrinsicHeight();
		if (width>600) {
			float change;
			change=600f/width;
			height=(int) (height*change);
			width=600;
		}
		drawable.setBounds(0, 0, width, height);
		sp.setSpan(new ImageSpan(drawable,path,ImageSpan.ALIGN_BASELINE) , start, end+mark.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		
		ClickableSpan click_span = new ClickableSpan() {
			@Override
			public void onClick(View widget) {
				if (onClick!=null) {
					onClick.onImageClick(widget,path);
				}
			}
		};
		
		ClickableSpan[] click_spans = sp.getSpans(start, end+mark.length()-1,
				ClickableSpan.class);
		if (click_spans.length != 0) {
			for (ClickableSpan c_span : click_spans) {
				sp.removeSpan(c_span);
			}
		}

		sp.setSpan(click_span, start, end+mark.length()-1,
				Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		
		((Editable) sp).delete(end+mark.length()-1, end+mark.length());
	}
	
	public Drawable compressImage(String source){
		BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
		bmpFactoryOptions.inJustDecodeBounds = true;
		Bitmap bmp = BitmapFactory.decodeFile(source, bmpFactoryOptions);
		int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
				/ (float)mContext.getResources().getDisplayMetrics().heightPixels);
		int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
				/ (float) mContext.getResources().getDisplayMetrics().widthPixels);
		if (heightRatio > 1 && widthRatio > 1) {
			if (heightRatio > widthRatio) {
				bmpFactoryOptions.inSampleSize = heightRatio;
			} else {
				bmpFactoryOptions.inSampleSize = widthRatio;
			}
		}
		bmpFactoryOptions.inJustDecodeBounds = false;
		bmp = BitmapFactory.decodeFile(source, bmpFactoryOptions);
		Drawable drawable=new BitmapDrawable(mContext.getResources(),bmp);
			int width=drawable.getIntrinsicWidth();
			int height=drawable.getIntrinsicHeight();
			if (width>600) {
				float change;
				change=600f/width;
				height=(int) (height*change);
				width=600;
			}
		drawable.setBounds(0, 0, width, height);
		return drawable;
	}
	
	public void setOnImageClickListener(OnImageClickListener onImageClick){
		onClick=onImageClick;
		
	}
	
	public interface OnSelectionChanged{
		public void onChanged(boolean inBlod,boolean inItalic,boolean inUnderline);
	}
	
	public interface OnImageClickListener{
		public void onImageClick(View v,String src);
	}
}
